using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using ProtoBuf;

namespace pd2_server_sdk.server
{
    public static class Router
    {
        private static readonly Dictionary<string, (MethodInfo method, object target, ParameterInfo[] parameters)>
            _routes = new Dictionary<string, (MethodInfo, object, ParameterInfo[])>();

        // 注册路由时记录方法参数信息
        public static void RegisterRoute(string path, MethodInfo method, object target)
        {
            _routes[path.ToLower()] = (method, target, method.GetParameters());
        }

        private static readonly Type[] parameterTypes = new Type[] { typeof(Stream) };

        // 修改后的 ExecuteRoute 方法（支持参数传递）
        public static void ExecuteRoute(string path, byte[] data)
        {
            if (!_routes.TryGetValue(path.ToLower(), out var route))
            {
                throw new ArgumentException($"Route not found: {path}");
            }

            var (method, target, parameters) = route;
            object[] args = null;

            // 处理参数反序列化
            if (parameters.Length > 0)
            {
                if (data == null)
                {
                    throw new ArgumentException($"Route '{path}' requires parameters, but no data provided");
                }

                // 获取第一个参数类型
                Type paramType = parameters[0].ParameterType;

                // 动态调用泛型反序列化方法
                if (paramType != typeof(byte[]))
                {
                    using (var stream = new MemoryStream(data))
                    {
                        MethodInfo deserializeMethod = typeof(Serializer).GetMethod("Deserialize", parameterTypes)?
                            .MakeGenericMethod(paramType);

                        if (deserializeMethod == null)
                        {
                            throw new InvalidOperationException("Serializer.Deserialize<T> method not found");
                        }

                        args = new[] { deserializeMethod.Invoke(null, new object[] { stream }) };
                    }
                }
                else
                {
                    args = new[] { data };
                }
            }

            // 调用目标方法
            try
            {
                method.Invoke(target, args);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Failed to execute route '{path}'", ex);
            }
        }
    }
}